package com.rattsoftware.client.views;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.Style.SortDir;
import com.extjs.gxt.ui.client.data.BaseModelData;
import com.extjs.gxt.ui.client.data.BasePagingLoadConfig;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.ModelIconProvider;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoader;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Controller;
import com.extjs.gxt.ui.client.mvc.Dispatcher;
import com.extjs.gxt.ui.client.mvc.View;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.util.IconHelper;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.rattsoftware.client.AppMessages;
import com.rattsoftware.client.Refreshable;
import com.rattsoftware.client.RefreshableEvent;
import com.rattsoftware.client.webclient;
import com.rattsoftware.client.events.AppEvents;
import com.rattsoftware.client.model.TimeTableSummary;
import com.rattsoftware.client.util.ProgressIndicator;
import com.rattsoftware.client.widgets.RemoteStoreFilterField;
import com.rattsoftware.client.widgets.SearchPagingToolBar;
import com.rattsoftware.server.admin.model.User;

public class TimeTableView extends View implements Refreshable{

	final AppMessages appMessages = GWT.create(AppMessages.class);
	private ContentPanel timeTableView;
	private LayoutContainer container;
	
	public static final int PAGE_SIZE = 10;

	Button newButton, editButton, deleteButton, newCourseUnit, viewCourseUnits;

	private Grid<TimeTableSummary> grid;
	private ColumnModel cm;
	SearchPagingToolBar<TimeTableSummary> toolBar;
	private PagingLoader<PagingLoadResult<TimeTableSummary>> loader;

	private List<TimeTableSummary> allStaffSummaries = new ArrayList<TimeTableSummary>();
	private User loggedInUser;
	
	public TimeTableView(Controller controller) {
		super(controller);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void handleEvent(AppEvent event) {
		if (event.getType() == AppEvents.Init) {
			initUI();
		}  else if (event.getType() == AppEvents.TimeTableView) {
			GWT.log("Handling TimeTableView Event in TimeTableView");
			LayoutContainer wrapper = (LayoutContainer) Registry
					.get(MainAppView.CENTER_PANEL);
			wrapper.removeAll();
			wrapper.add(container);
			wrapper.layout();
			return;
		}
	}

	protected void initUI() {
		timeTableView = new ContentPanel();
		timeTableView.setHeading("Time Table Management");
		timeTableView.setAnimCollapse(false);
		timeTableView.addListener(Events.Expand, new Listener<ComponentEvent>() {
			public void handleEvent(ComponentEvent be) {
				Dispatcher.get().dispatch(AppEvents.TimeTableView);
			}
		});

		timeTableView.add(addSubMenus());
		
		ContentPanel west = (ContentPanel) Registry.get(MainAppView.WEST_PANEL);
		west.add(timeTableView);
	}
	
	@Override
	protected void initialize() {
		container = new LayoutContainer();

		GWT.log("StaffView : initialize");
		
		ProgressIndicator.showProgressBar();

		List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
		configs.add(new ColumnConfig("staffId", appMessages.id(), 20));
		configs.add(new ColumnConfig("title", appMessages.title(),100));
		configs.add(new ColumnConfig("firstName", appMessages.firstName(),120));
		configs.add(new ColumnConfig("lastName", appMessages.lastName(), 120));
		configs.add(new ColumnConfig("gender", appMessages.gender(), 50));
		configs.add(new ColumnConfig("department", appMessages.departmentName(),200));
		configs.add(new ColumnConfig("dateOfBirth", appMessages.dateOfBirth(),90));
		configs.add(new ColumnConfig("phoneNumber", appMessages.phoneNo(),90));
		configs.add(new ColumnConfig("emailAddress", appMessages.emailAddress(),100));
		configs.add(new ColumnConfig("residentialAddress", appMessages.residentialAddress(), 130));
		configs.add(new ColumnConfig("employmentType", appMessages.employmentType(), 100));
		configs.add(new ColumnConfig("staffType", appMessages.staffType(), 90));

		cm = new ColumnModel(configs);
		cm.setHidden(0, true); // hide ID column

		toolBar = new SearchPagingToolBar<TimeTableSummary>(PAGE_SIZE);
		
		loader = new BasePagingLoader<PagingLoadResult<TimeTableSummary>>(
				new RpcProxy<PagingLoadResult<TimeTableSummary>>() {
					@Override
					public void load(
							Object loadConfig,
							final AsyncCallback<PagingLoadResult<TimeTableSummary>> callback) {
						ProgressIndicator.showProgressBar();
						final PagingLoadConfig pagingLoadConfig = (PagingLoadConfig) loadConfig;
						if (pagingLoadConfig.getSortField() == null
								|| pagingLoadConfig.getSortField().trim()
										.equals("")) {
							pagingLoadConfig.setSortField("name");
							pagingLoadConfig.setSortDir(SortDir.ASC);
						}
						pagingLoadConfig.set(RemoteStoreFilterField.PARM_FIELD,
								"name");
						pagingLoadConfig.set(RemoteStoreFilterField.PARM_QUERY,
								toolBar.getSearchFilterValue());
						GWT.log("StaffView RpcProxy:load loadConfig pageSize="
								+ pagingLoadConfig.getLimit() + " sortField="
								+ pagingLoadConfig.getSortField() + " filter="
								+ toolBar.getSearchFilterValue());
						Scheduler.get().scheduleDeferred(
								new ScheduledCommand() {
									@Override
									public void execute() {
										//final StaffController controller = (StaffController) StaffView.this.getController();
										/*try {
											controller.getStaffList(pagingLoadConfig, callback);
										} catch (RattsParsingException e) {
											e.printStackTrace();
										}*/
									}
								});
					}
				});

		loader.setRemoteSort(true);
		toolBar.bind(loader);

		ListStore<TimeTableSummary> store = new ListStore<TimeTableSummary>(loader);
		grid = new Grid<TimeTableSummary>(store, cm);
		grid.setAutoExpandColumn("department");
		grid.setAutoExpandMax(10000);
		grid.setStripeRows(true);
		grid.setBorders(true);

		// new
		newButton = new Button(appMessages.newStaff());
		newButton.setIcon(IconHelper.createStyle("staff-add"));
		newButton.addListener(Events.Select, new Listener<ButtonEvent>() {
			@Override
			public void handleEvent(ButtonEvent be) {
				//addNewStaff();
			}
		});

		// edit
		editButton = new Button(appMessages.editStaff());
		editButton.setIcon(IconHelper.createStyle("edit"));
		editButton.addListener(Events.Select, new Listener<ButtonEvent>() {
			@Override
			public void handleEvent(ButtonEvent be) {
				//editStaff();
			}
		});

		// delete
		deleteButton = new Button(appMessages.deleteStaff());
		deleteButton.setIcon(IconHelper.createStyle("staff-delete"));
		deleteButton.addListener(Events.Select, new Listener<ButtonEvent>() {
			@Override
			public void handleEvent(ButtonEvent be) {
				//deleteStaff();
			}
		});

		// new course unit
		viewCourseUnits = new Button(appMessages.viewCourseUnits());
		viewCourseUnits.setIcon(IconHelper.createStyle("view"));
		viewCourseUnits.addListener(Events.Select, new Listener<ButtonEvent>() {
			@Override
			public void handleEvent(ButtonEvent be) {
				//newCourseUnit();
			}
		});

		/*// view course units
		viewCourseUnits = new Button(appMessages.viewCourseUnits());
		viewCourseUnits.setIcon(IconHelper.createStyle("view"));
		viewCourseUnits.addListener(Events.Select, new Listener<ButtonEvent>() {
			@Override
			public void handleEvent(ButtonEvent be) {
				//showCourseUnits();
			}
		});*/

		checkLoggedInUserPermissions();

		ToolBar toolBar = new ToolBar();
		toolBar.setSpacing(10);
		toolBar.add(newButton);
		toolBar.add(editButton);
		toolBar.add(deleteButton);
		toolBar.add(viewCourseUnits);
		//toolBar.add(newCourseUnit);


		Scheduler.get().scheduleDeferred(new ScheduledCommand() {
			@Override
			public void execute() {
				// load the first set of data
				PagingLoadConfig config = new BasePagingLoadConfig(0, PAGE_SIZE);
				loader.load(config);
			}
		});

		getView(appMessages.registeredStaff(), grid, toolBar);
	}
	
	private void addNewStaff() {
		ProgressIndicator.showProgressBar();
		Scheduler.get().scheduleDeferred(new ScheduledCommand() {
			@Override
			public void execute() {
				//StaffController controller = (StaffController) getController();
				//controller.forwardToNewStaffController();
			}
		});
	}
	
	private void editStaff() {
		if (grid.getSelectionModel().getSelectedItem() != null) {
			ProgressIndicator.showProgressBar();
			Scheduler.get().scheduleDeferred(new ScheduledCommand() {
				@Override
				public void execute() {
					//StaffSummary staffSummary = grid.getSelectionModel()
					//		.getSelectedItem();
					//StaffController controller = (StaffController) getController();
					//controller.forwardToEditStaffController(staffSummary);
				}
			});
		} else {
			MessageBox.alert(appMessages.registeredStaff(), appMessages
					.staffNotSelected(), null);
		}
	}
	
	private void deleteStaff() {

		// listener for message box events.
		final Listener<MessageBoxEvent> messageBoxListener = new Listener<MessageBoxEvent>() {
			@Override
			public void handleEvent(MessageBoxEvent be) {
				Button btn = be.getButtonClicked();

				if (btn.getText().equalsIgnoreCase("OK")) {
					ProgressIndicator.showProgressBar();
					Scheduler.get().scheduleDeferred(new ScheduledCommand() {
						@Override
						public void execute() {
							//StaffSummary courseSummary = grid
							//		.getSelectionModel().getSelectedItem();
							//StaffController controller = (StaffController) getController();
							// controller.forwardToEditWizard(userSummary);
						}
					});
				}
			}
		};

		if (grid.getSelectionModel().getSelectedItem() != null) {
			MessageBox.confirm(appMessages.confirm(), appMessages
					.confirmStaffDelete(), messageBoxListener);

		} else {
			MessageBox.alert(appMessages.registeredStaff(), appMessages
					.staffNotSelected(), null);
		}
	}

	public void setAllStaffSummaries(List<TimeTableSummary> staffSummary) {
		this.allStaffSummaries = staffSummary;
	}
	
	public List<TimeTableSummary> getStaffSummaries() {
		return allStaffSummaries;
	}
	
	private ModelData newItem(String text, String iconStyle) {
		ModelData m = new BaseModelData();
		m.set("name", text);
		m.set("icon", iconStyle);
		return m;
	}

	@Override
	public void refresh(RefreshableEvent event) {
		GWT.log("Refreshing...");
		if (event.getEventType() == RefreshableEvent.Type.UPDATE_STAFF) {
			//Staff staff = event.getData();
			ListStore<TimeTableSummary> store = grid.getStore();
			/*TimeTableSummary summary = getStaffSummary(staff.getId());
			if (summary != null) {
				summary.updateStaffSummary(staff);
				store.update(summary);
			}*/
		} else if (event.getEventType() == RefreshableEvent.Type.CREATE_STAFF) {
			//Staff staff = event.getData();
			ListStore<TimeTableSummary> store = grid.getStore();
			//TimeTableSummary summary = new StaffSummary(staff);
			//store.add(summary);
		} else if (event.getEventType() == RefreshableEvent.Type.REFRESH_STAFF_LIST) {
			toolBar.refresh();
		}
	}
	
	TimeTableSummary getTimeTableSummary(String userId) {
		String userIdStr = String.valueOf(userId);
		for (TimeTableSummary userSummary : grid.getStore().getModels()) {
			/*if (userIdStr.equals(userSummary.getId())) {
				return userSummary;
			}*/
		}
		GWT.log("ERROR: no user summary found id=" + userId);
		return null;
	}

	private TreePanel<ModelData> addSubMenus() {
		TreeStore<ModelData> store = new TreeStore<ModelData>();
		TreePanel<ModelData> tree = new TreePanel<ModelData>(store);
		tree.setIconProvider(new ModelIconProvider<ModelData>() {

			public AbstractImagePrototype getIcon(ModelData model) {
				if (model.get("icon") != null) {
					return IconHelper.createStyle((String) model.get("icon"));
				} else {
					return null;
				}
			}

		});

		tree.setDisplayProperty("name");
		tree.setAutoSelect(true);

		ModelData m = newItem("Exam TimeTable", "exam_tt");
		store.add(m, false);

		m = newItem("Class TimeTable ", "class_tt");
		store.add(m, false);

		tree.getSelectionModel().addSelectionChangedListener(
				new SelectionChangedListener<ModelData>() {
					@Override
					public void selectionChanged(
							SelectionChangedEvent<ModelData> se) {
						ModelData f = (ModelData) se.getSelection().get(0);
						GWT.log("Selected Item ***** " + f.get("name"));

					}
				});
		return tree;
	}
	
	private void getView(String title, Component component,
			Component topComponent) {
		GWT.log("StaffView : Initialising Window");

		BorderLayout layout = new BorderLayout();
		layout.setEnableState(false);
		container.setLayout(layout);

		ContentPanel cp = new ContentPanel();
		cp.setLayout(new FitLayout());
		cp.setHeading("Staff Management");
		cp.setBorders(false);
		cp.add(component);
		cp.setBottomComponent(toolBar);
		cp.setTopComponent(topComponent);

		container.add(cp, new BorderLayoutData(LayoutRegion.CENTER));
	}
	
	private User getLoggedInUser() {
		if (loggedInUser == null) {
			loggedInUser = Registry.get(webclient.LOGGED_IN_USER_NAME);
		}
		return loggedInUser;
	}
	
	private void checkLoggedInUserPermissions() {
		if (getLoggedInUser() == null) {
			GWT.log("Could not find logged in user, so could not determine permissions");
			return;
		}
		// if (loggedInUser.hasPermission(Permission.PERM_ADD_COURSE)) {
		newButton.show();
		// }
		// if (loggedInUser.hasPermission(Permission.PERM_EDIT_COURSE)) {
		editButton.show();
		// }
		// if (loggedInUser.hasPermission(Permission.PERM_VIEW_COURSE)) {
		viewCourseUnits.show();
		// }
		// if (loggedInUser.hasPermission(Permission.PERM_DELETE_COURSE)) {
		deleteButton.show();
		// }
	}
}
